/***************************************************************************************
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
*
* NEMU is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*          http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
***************************************************************************************/

#include "./sdb.h"

#define NR_WP 32

static WP wp_pool[NR_WP] = {};
static WP *head = NULL, *free_ = NULL;

WP* get_head(){
  return head;
}

void init_wp_pool() {
  int i;
  for (i = 0; i < NR_WP; i ++) {
    wp_pool[i].NO = i;
    wp_pool[i].next = (i == NR_WP - 1 ? NULL : &wp_pool[i + 1]);
  }

  head = NULL;
  free_ = wp_pool;
}

/* TODO: Implement the functionality of watchpoint */
WP* new_wp(){
  if(free_ == NULL) {
    printf("No free watchpoint");
    assert(0);
  }
  WP* node = free_;
  free_ = free_->next;
  node->next = head;
  head = node;
  return node;
}

void free_wp(WP *wp){
  if(wp == head){
    head = (*head).next;
    wp->next = free_;
    free_ = wp;
  }
  else{
    WP *wp_next = (*wp).next;
    WP* pre = head;
    while((*pre).next != wp){
      pre = (*pre).next;
    }
    (*pre).next = wp_next;
    (*wp).next = free_;
    free_ = wp;
  }
  return;
}

void free_wp_by_NO(int n){
  if(head != NULL && head->NO == n){
    WP* wp = head;
    head = (*head).next;
    wp->next = free_;
    free_ = wp;
    free(wp->expression);
  }
  else{
    WP* pre = head;
    while(pre->next->NO != n){
      pre = pre->next;
    }
    WP* wp = pre->next;
    pre->next = pre->next->next;
    wp->next = free_;
    free_ = wp;
    free(wp->expression);
  }
  return;
}
